<template>
  <!-- 删除员工导入导出员工有使用按钮级别权限 -->
  <div class="dashboard-container">
    <div class="app-container">
      <!-- 自定义头部组件 -->
      <PageTools>
        <template #left>总记录条数：{{ total }}条</template>
        <!-- 自定义指令按钮级别权限 -->
        <el-button v-check="'POINT-USER-IMPORT'" size="small" type="success" @click="$router.push('/import?type=employee')">导入</el-button>
        <el-button v-check="'POINT-USER-EXPORT'" size="small" type="warning" @click="exportExcel">导出</el-button>
        <!-- 让showDialog变为true -->
        <el-button size="small" type="primary" @click="showDialog = true">新增员工</el-button>
      </PageTools>
      <!-- 卡片 -->
      <el-card v-loading="loading" element-loading-text="拼命加载中...">
        <!-- 表格 -->
        <el-table border :data="tableData">
          <!-- 每一列 -->
          <el-table-column label="序号" width="100" align="center" type="index" :index="indexMethod" />
          <el-table-column label="姓名" align="center" prop="username" />
          <el-table-column label="头像" align="center">
            <template v-slot="{row}">
              <!-- 自定义指令 v-imgerror  图片加载失败会显示默认图片 -->
              <!-- 在 .vue 文件中通过相对路径引用本地图片时，需要在图片的链接外包上一层 require()，
                  将图片 URL 转换为 webpack 模块请求，并结合 file-loader 或者 url-loader 进行处理。
              -->
              <img
                v-imgerror="require('@/assets/common/bigUserHeader.png')"
                :src="row.staffPhoto"
                width="80"
                height="80"
                alt=""
                @click="showCode(row.staffPhoto)"
              >
            </template>
          </el-table-column>
          <el-table-column label="工号" align="center" prop="workNumber" />
          <!-- formatter 用来格式化内容 是一个函数Function(row, column, cellValue, index)里面有一些数据 -->
          <el-table-column
            label="聘用形式"
            align="center"
            prop="formOfEmployment"
            :formatter="formatEmployment"
          />
          <el-table-column label="部门" align="center" prop="departmentName" />
          <el-table-column label="入职时间" align="center">
            <template v-slot="{ row }">
              {{ row.timeOfEntry | time }}
            </template>
          </el-table-column>
          <el-table-column label="账户状态" align="center">
            <template v-slot="{ row }">
              <!-- active-color打开的颜色 -->
              <!-- inactive-color关闭的颜色 -->
              <!-- <el-switch
                :value="row.enableState === 1"
                active-color="#13ce66"
                inactive-color="#ff4949"
              /> -->
              {{ row.enableState === 1 ? '可用' : '禁用' }}
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="280">
            <template v-slot="{row}">
              <el-button type="text" size="small" @click="$router.push(`/employees/detail/${row.id}`)">查看</el-button>
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button type="text" size="small" @click="assign(row.id)">角色</el-button>
              <el-button v-check="'POINT-USER-DELETE'" type="text" size="small" @click="del(row.id)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <el-row type="flex" justify="end" align="middle" style="height: 60px">
          <el-pagination
            layout="prev, pager, next, jumper"
            :total="total"
            :page-size="size"
            :current-page="page"
            background
            @current-change="change"
          />
        </el-row>
      </el-card>
      <!-- 新增员工弹窗组件 -->
      <AddEmployee :show-dialog.sync="showDialog" @getEmployeeList="getEmployeeList" @Pagination="Pagination" />
      <!-- 二维码弹层，弹层随便放哪 -->
      <el-dialog title="二维码" :visible.sync="showCodeDialog">
        <el-row type="flex" justify="center">
          <canvas ref="myCanvas" />
        </el-row>
      </el-dialog>
      <!-- 父组件找到子组件调用方法 -->
      <!-- <AssignRole ref="assign" :show-role-dialog.sync="showRoleDialog" :user-id="userId" /> -->
      <!-- 就直接在子组件中操作 -->
      <AssignRole :show-role-dialog.sync="showRoleDialog" :user-id="userId" />
    </div>
  </div>
</template>

<script>
import Qrcode from 'qrcode' // 用于生成二维码
import moment from 'moment'
import employeesEnum from '@/api/constant/employees'
import { delEmployee, getEmployeeList } from '@/api/employees'
// 引入新增员工组件
import AddEmployee from './components/AddEmployee.vue'
// 引入分配角色弹窗
import AssignRole from './components/AssignRole.vue'
export default {
  name: 'Employees',
  // 使用组件
  components: {
    AddEmployee,
    AssignRole
  },
  data() {
    return {
      // 员工列表
      tableData: [],
      // 页码
      page: 1,
      // 每页显示的条数
      size: 5,
      // 总数量
      total: 0,
      // 加载状态
      loading: false,
      // 枚举
      hireType: employeesEnum.hireType,
      // 控制新增员工弹窗
      showDialog: false,
      // 控制二维码弹层
      showCodeDialog: false,
      // 控制分配角色弹窗
      showRoleDialog: false,
      // 当前用户的id
      userId: ''
    }
  },
  created() {
    this.getEmployeeList()
  },
  methods: {
    // 获取员工列表
    async getEmployeeList() {
      // 一来为加载状态
      this.loading = true
      const res = await getEmployeeList(this.page, this.size)
      // console.log(res)
      // 获取员工数据赋值给tableData
      this.tableData = res.rows
      // 获取总数赋值给total
      this.total = res.total
      // 拿到数据后取消加载状态
      this.loading = false
    },
    // 分页器切换
    change(value) {
      this.page = value
      this.getEmployeeList()
    },
    // 序号问题
    indexMethod(index) {
      // 序号应该是 当前页码减一乘以每页显示的条数加上index+1
      // 每页显示5条的话，第三页应该是11开始，第三页的页码乘以每页的数量会等于15，要减去一个页码，index是从0开始所以要加1
      return (this.page - 1) * this.size + index + 1
    },
    // 删除员工
    async del(id) {
      // 给提示是否删除员工
      try {
        await this.$confirm('此操作将永久删除该员工, 是否继续?', '提示', {
          type: 'warning'
        })
      } catch {
        return
      }
      // 删除有可能会删除默认数据然后失败，如果不放在try中，只有一条数据，而且是默认数据，删除不了，就会一直往前
      // 放在try中，只有请求成功才会让page减一，失败就不会减一
      try {
        // 点击了确定，发请求删除
        await delEmployee(id)
        // 如果只剩一条数据，删除后获取上一页的数据
        if (this.tableData.length === 1) {
          this.page--
        }
      } catch {
        return
      }
      // 删除成功给提示,重新渲染
      this.$message.success('删除员工成功')
      this.getEmployeeList()
    },
    // 用来格式化内容
    formatEmployment(row, column, cellValue, index) {
      // 从hireType中查找id和自己一样的那一行的id，找到了就把自己的value给他
      // 后台传过来的id有些是字符窜类型的，而我们跟后台约定好的数据是number类型的，需要把获取到的数据转换成number类型的
      // return this.hireType.find(item => {
      //   if (cellValue === null) {
      //     return item.id === cellValue
      //   }
      //   return item.id === +cellValue
      // }).value
      // 三元表达式 如果是null转number会变成0，匹配不到也会爆value的错
      return this.hireType.find(item => cellValue === null ? item.id === cellValue : item.id === +cellValue).value
    },
    // 子组件添加成功员工后，分页器跳到最后
    Pagination() {
      this.total++
      this.page = Math.ceil(this.total / this.size)
    },
    /*
      导出
      核心思路：
        1. 需要用到一个方法 Export2Excel 文件中的export_json_to_excel
        注意：为了性能优化，这里使用的是异步的导入
    */
    async exportExcel() {
      const excel = await import('@/utils/Export2Excel')
      // 发送ajax请求，获取所有员工的数据
      const { rows } = await getEmployeeList(1, 1000) // 直接解构出 rows
      // console.log(rows)
      const userRelations = {
        '姓名': 'username',
        '手机号': 'mobile',
        '工号': 'workNumber',
        '聘用形式': 'formOfEmployment',
        '入职日期': 'timeOfEntry',
        '转正日期': 'correctionTime',
        '部门': 'departmentName'
      }
      // Object.keys可以获取对象中的键 Object.values可以获取对象中的值
      const header = Object.keys(userRelations)
      // 需要这样的格式 ['入职日期', '手机号', '姓名']
      const data = [] // 用于保存数据
      // 遍历每个对象
      rows.forEach(item => {
        // 创建一个空数组
        const arr = []
        // 根据表头遍历
        header.forEach(h => {
          // 判断时间 如果是时间需要转换
          if (h === '入职日期' || h === '转正日期') {
            // 把日期保存到time中
            let time = item[userRelations[h]]
            // 如果有值才需要转换，没值就不用转换
            if (time) {
              // 把日期用moment转换
              time = moment(item[userRelations[h]]).format('YYYY-MM-DD')
            }
            // 最后统一添加
            arr.push(time)
          } else if (h === '聘用形式') {
            // 如果是聘用形式，就在hireType中查找，如果找到对应的，就保留下来
            const result = this.hireType.find(v => v.id === +item[userRelations[h]])
            // 如果有值就显示这个值的名字，没有就显示其他
            arr.push(result ? result.value : '其他')
          } else {
            // 没有额外的判断直接添加
            // 把对应的数据添加到arr数组中 [userRelations[h]就是username mobile
            // item[userRelations[h]] 就是根据表头拿到的rows里的值
            arr.push(item[userRelations[h]])
          }
        })
        // 最后添加到data中
        data.push(arr)
      })
      // 生成excel表格
      excel.export_json_to_excel({
        header,
        data,
        filename: '员工数据',
        bookType: 'xlsx'
      })
    },
    // 展示二维码
    async showCode(photo) {
      this.showCodeDialog = true
      // 因为弹层刚显示，弹层里的东西需要渲染，没有等待，直接就通过this.$refs会找不到，就会报错，要先等一等用nextTick
      await this.$nextTick()
      // dom：把二维码生成到哪个DOM上 第一个参数
      // info: 生成二维码的信息  可以是一个url地址  文本 图片  第二个参数
      Qrcode.toCanvas(this.$refs.myCanvas, photo)
    },
    assign(id) {
      this.userId = id
      this.showRoleDialog = true
      // 父组件调用子组件的方法
      // this.$refs.assign.getRoleList()
    }
  }
}
</script>

<style>

</style>
